﻿#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

//int main()
//{
//	/*
//	* 方法的原理是a对b进行两次异或运算得到的还是a
//	* 即
//	* b=a^a^b
//	* a=b^b^a
//	*/
//	int a = 10;
//	int b = 20;
//	a = a ^ b;
//	b = a ^ b;//a^b^b
//	a = a ^ b;//a^b^a
//	printf("a=%d,b=%d",a,b);
//	return 0;
//}


//此种方法只对正整数有效
/*
* 
整数在内存中以补码的方式存储
正数的补码是它本身，
负数的补码是原码转反码然后再+1得到的
所以不能直接利用求余数的方式求解1的个数
*/
//int main()
//{
//	int num = -108;
//	int count = 0;//计数
//	while (num)
//	{
//		if (num % 2 == 1)
//			count++;
//		num = num / 2;
//	}
//	printf("⼆进制中1的个数 = %d\n", count);
//	return 0;
//}
//这种方法是正确的，
// 正确的原因应该是使用&运算符时，其实就是直接使用的存储在内存中的补码进行计算的。
// 因为我们日常只会对正整数进行&等运算，所以会看不出区别（因为正整数的原码和补码是一致的）
//int main()
//{
//	int num = 108;
//	int i = 0;
//	int count = 0;//计数
//	for (i = 0; i < 32; i++)
//	{
//		if (num & (1 << i))
//			count++;
//	}
//	printf("⼆进制中1的个数 = %d\n", count);
//	return 0;
//}


//练习2：⼆进制位置0或者置1
//编写代码将13⼆进制序列的第5位修改为1，然后再改回0
//int main()
//{
//	int num = 13;
//	
//	printf("修改前 = %d\n", num);
//	printf("⼆进制序列的第5位修改为1 = %d\n", num|(0x01<<5));
//	printf("⼆进制序列的第5位改回0 = %d\n", num & ~(0x01 << 5));
//	return 0;
//}

//逗号表达式
//逗号表达式，从左向右依次执⾏。整个表达式的结果是最后⼀个表达式的结果。
int main()
{
	int a,b,c=8;
	//这种初始化方式不能初始化变量a,b，只会初始化变量c，
	// 因为逗号运算符是从左向右依次运算，所以拆开看就是
	//int a -> int b -> int c=8
//如果想同时初始化多个局部变量可以这样
	int d=8, e = 9, f = 10;
	//int g = h = i = 0;//这种是错误的，因为未对h,i进行数据类型定义

	//逗号运算符和括号
	c = (e, f);//此处由于括号的存在，先运算括号内的计算
	printf("c = %d\n", c);
	printf("f = %d\n", f);
	d = e, f=0;//此处没有括号，由于赋值运算符的优先级比逗号运算符高，所以先进行赋值运算，然后再执行逗号运算符后面的运算
	printf("d = %d\n", d);
	printf("f = %d\n", f);
	return 0;
}


/*
* 即使有了操作符的优先级和结合性，我们写出的表达式依然有可能不能通过操作符的属性确定唯⼀的
计算路径，那这个表达式就是存在潜在⻛险的，建议不要写出特别复杂的表达式
*/